home *** CD-ROM | disk | FTP | other *** search
- /*
- *=============================================================================
- * tSippCamera.c
- *-----------------------------------------------------------------------------
- * Tcl commands to manage SIPP camera.
- *-----------------------------------------------------------------------------
- * Copyright 1992 Mark Diekhans
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies. Mark Diekhans makes
- * no representations about the suitability of this software for any purpose.
- * It is provided "as is" without express or implied warranty.
- *-----------------------------------------------------------------------------
- * $Id: tSippCamera.c,v 2.0 1992/11/02 03:56:24 markd Rel $
- *=============================================================================
- */
-
- #include "tSippInt.h"
- /*
- * Internal function prototypes.
- */
- static Camera *
- CameraHandleToPtr _ANSI_ARGS_((tSippGlob_pt tSippGlobPtr,
- char *handle));
-
- static bool
- ProcessCameraParms _ANSI_ARGS_((tSippGlob_pt tSippGlobPtr,
- Camera *camera,
- int argc,
- char **argv));
-
- /*=============================================================================
- * CameraHandleToPtr --
- * Utility procedure to convert a camera handle to a camera pointer.
- * Parameters:
- * o tSippGlobPtr (I) - A pointer to the Tcl SIPP global structure.
- * o handle (I) - A camera handle.
- * Returns:
- * A pointer to the camera, or NULL if an error occured.
- *-----------------------------------------------------------------------------
- */
- static Camera *
- CameraHandleToPtr (tSippGlobPtr, handle)
- tSippGlob_pt tSippGlobPtr;
- char *handle;
- {
- Camera **cameraEntryPtr;
-
- if (STREQU (handle, "STDCAMERA"))
- handle = "camera0";
-
- cameraEntryPtr = (Camera **)
- Tcl_HandleXlate (tSippGlobPtr->interp,
- tSippGlobPtr->cameraTblPtr, handle);
- if (cameraEntryPtr == NULL)
- return NULL;
- return *cameraEntryPtr;
-
- } /* CameraHandleToPtr */
-
- /*=============================================================================
- * ProcessCameraParms --
- * Process the arguments for the SippCameraCreate and SippCameraParms
- * commands. These arguments are in the form:
- * [position] [point] [upvector] [focal]
- *
- * Parameters:
- * o tSippGlobPtr (I) - A pointer to the Tcl SIPP global structure.
- * o camera (I) - The apply the parameters to.
- * o argc (I) - The argument count, only including the arguments to process.
- * o argv (I) - The argument vector, starting with the first option to
- * process.
- * Returns:
- * TRUE is ok, FALSE if an error occured (message in interp).
- *-----------------------------------------------------------------------------
- */
- static bool
- ProcessCameraParms (tSippGlobPtr, camera, argc, argv)
- tSippGlob_pt tSippGlobPtr;
- Camera *camera;
- int argc;
- char **argv;
- {
- Vector position, point, upVector, viewVector;
- double focal, dotProduct;
- bool setPosition, setPoint, setUp, setFocal;
-
- setPosition = setPoint = setUp = setFocal = FALSE;
- if ((argc > 0) && (argv [0][0] != '\0'))
- setPosition = TRUE;
- if ((argc > 1) && (argv [1][0] != '\0'))
- setPoint = TRUE;
- if ((argc > 2) && (argv [2][0] != '\0'))
- setUp = TRUE;
- if ((argc > 3) && (argv [3][0] != '\0'))
- setFocal = TRUE;
-
- if (setPosition && !TSippConvertVertex (tSippGlobPtr, argv [0], &position))
- return FALSE;
- if (setPoint && !TSippConvertVertex (tSippGlobPtr, argv [1], &point))
- return FALSE;
- if (setUp && !TSippConvertVertex (tSippGlobPtr, argv [2], &upVector))
- return FALSE;
- if (setFocal && (Tcl_GetDouble (tSippGlobPtr->interp, argv [3],
- &focal) != TCL_OK))
- return FALSE;
-
- /*
- * Check the the position and point are not the same and that the view
- * and up vectors are not parallel. First gather the current camera
- * settings for the values that were not specified.
- */
- if (!setPosition)
- position = camera->position;
- if (!setPoint)
- point = camera->lookat;
- if (!setUp)
- upVector = camera->up;
-
- if (FEQUAL (position.x, point.x) && FEQUAL (position.y, point.y) &&
- FEQUAL (position.z, point.z)) {
- Tcl_AppendResult (tSippGlobPtr->interp, "The position and point ",
- "may not be the same", (char *) NULL);
- return FALSE;
- }
-
- viewVector.x = point.x - position.x;
- viewVector.y = point.y - position.y;
- viewVector.z = point.z - position.z;
- vecnorm (&viewVector);
- vecnorm (&upVector);
-
- dotProduct = fabs (VecDot (viewVector, upVector));
- if (FEQUAL (dotProduct, 1.0)) {
- Tcl_AppendResult (tSippGlobPtr->interp, "The view vector (position ",
- "to point) and up vector may not be parallel",
- (char *) NULL);
- return FALSE;
- }
-
- /*
- * Now set the requested values.
- */
- if (setPosition)
- camera_position (camera, position.x, position.y, position.z);
- if (setPoint)
- camera_look_at (camera, point.x, point.y, point.z);
- if (setUp)
- camera_up (camera, upVector.x, upVector.y, upVector.z);
- if (setFocal)
- camera_focal (camera, focal);
- return TRUE;
-
- } /* ProcessCameraParms */
-
- /*=============================================================================
- * SippCameraCreate --
- * Implements the command:
- * SippCameraCreate [position] [point] [upvector] [focal]
- *
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippCameraCreate (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- Camera *camera;
- Camera **cameraEntryPtr;
-
- if (argc > 5) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0],
- " [position] [point] [upvector] [focal]",
- (char *) NULL);
- return TCL_ERROR;
- }
- camera = camera_create ();
- if (!ProcessCameraParms (tSippGlobPtr, camera, argc - 1, &argv [1])) {
- camera_destruct (camera);
- return TCL_ERROR;
- }
- cameraEntryPtr = (Camera **) Tcl_HandleAlloc (tSippGlobPtr->cameraTblPtr,
- tSippGlobPtr->interp->result);
- *cameraEntryPtr = camera;
- return TCL_OK;
-
- } /* SippCameraCreate */
-
- /*=============================================================================
- * SippCameraDestruct --
- * Implements the command:
- * SippCameraDestruct cameralist
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippCameraDestruct (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- handleList_t cameraList;
- handleList_t cameraEntryList;
- int idx;
-
- if (argc != 2) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0], " cameralist",
- (char *) NULL);
- return TCL_ERROR;
- }
- if (!TSippHandleListConvert (tSippGlobPtr, tSippGlobPtr->cameraTblPtr,
- argv [1], &cameraList, &cameraEntryList))
- return TCL_ERROR;
-
- for (idx = 0; idx < cameraList.len; idx++) {
- camera_destruct ((Camera *) cameraList.ptr [idx]);
- Tcl_HandleFree (tSippGlobPtr->cameraTblPtr, cameraEntryList.ptr [idx]);
- }
-
- TSippHandleListFree (&cameraList);
- TSippHandleListFree (&cameraEntryList);
- return TCL_OK;
-
- } /* SippCameraDestruct */
-
- /*=============================================================================
- * SippCameraParams --
- * Implements the command:
- * SippCameraParams camera [position] [point] [upvector] [focal]
- *
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippCameraParams (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- Camera *camera;
-
- if ((argc < 2) || (argc > 6)) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0],
- " camera [position] [point] [upvector] [focal]",
- (char *) NULL);
- return TCL_ERROR;
- }
- camera = CameraHandleToPtr (tSippGlobPtr, argv [1]);
- if (camera == NULL)
- return TCL_ERROR;
-
- if (!ProcessCameraParms (tSippGlobPtr, camera, argc - 2, &argv [2])) {
- return TCL_ERROR;
- }
- return TCL_OK;
-
- } /* SippCameraParams */
-
- /*=============================================================================
- * SippCameraUse --
- * Implements the command:
- * SippCameraUse camera
- *
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippCameraUse (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- Camera *camera;
-
- if (argc != 2) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0], " camera",
- (char *) NULL);
- return TCL_ERROR;
- }
- camera = CameraHandleToPtr (tSippGlobPtr, argv [1]);
- if (camera == NULL)
- return TCL_ERROR;
-
- camera_use (camera);
- return TCL_OK;
-
- } /* SippCameraUse */
-
- /*=============================================================================
- * TSippCameraInit --
- * Initialized the camera commands and set up STDCAMERA as the current
- * camera.
- *
- * Parameters:
- * o tclSippGlobP (I) - Pointer to the top level global data structure.
- * (currently unused).
- *-----------------------------------------------------------------------------
- */
- void
- TSippCameraInit (tSippGlobPtr)
- tSippGlob_pt tSippGlobPtr;
- {
- Camera *camera;
- Camera **cameraEntryPtr;
-
- static tSippTclCmdTbl_t cmdTable [] = {
- {"SippCameraCreate", SippCameraCreate},
- {"SippCameraDestruct", SippCameraDestruct},
- {"SippCameraParams", SippCameraParams},
- {"SippCameraUse", SippCameraUse},
- {NULL, NULL}
- };
-
- tSippGlobPtr->cameraTblPtr =
- Tcl_HandleTblInit ("camera", sizeof (Object *), 24);
-
- TSippInitCmds (tSippGlobPtr, cmdTable);
-
- /*
- * Set up the standard camera entry `STDCAMERA'. Allocate a new camera
- * rather than useing the SIPP default so it can be deleted.
- */
- camera = camera_create ();
- camera_params (camera, 0.0, 0.0, 10.0, 0.0, 0.0, 0.0,
- 0.0, 1.0, 0.0, 0.25);
- camera_use (camera);
-
- cameraEntryPtr = (Camera **) Tcl_HandleAlloc (tSippGlobPtr->cameraTblPtr,
- tSippGlobPtr->interp->result);
- *cameraEntryPtr = camera;
-
-
- } /* TSippCameraInit */
-